-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Zvkned: add infrastructure for Zvkned #752
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few random low-level Sail comments (I know nothing about the actual spec).
Also how was it tested against QEMU exactly? It would be nice to integrate tests like that (in future; we don't have the infrastructure for it yet).
model/riscv_insts_zvkned.sail
Outdated
let LMUL = if LMUL_pow < 0 then 0 else LMUL_pow; | ||
let num_elem = get_num_elem(LMUL_pow, SEW); | ||
|
||
if (zvk_check_elements(VLEN, num_elem, LMUL, SEW) == false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (zvk_check_elements(VLEN, num_elem, LMUL, SEW) == false) | |
if not(zvk_check_elements(VLEN, num_elem, LMUL, SEW)) |
(And in the other places.)
model/riscv_insts_zvkned.sail
Outdated
|
||
val aes_rotword : bits(32) -> bits(32) | ||
function aes_rotword(x) = { | ||
let a0 : bits (8) = x[ 7.. 0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would just simplify this to
function aes_rotword(x) = x[7 .. 0] @ x[15 .. 8] @ x[23 .. 16] @ x[31 .. 24]
model/riscv_insts_zvkned.sail
Outdated
} else { | ||
let 'n = num_elem; | ||
let 'm = SEW; | ||
assert('m == 32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessarily true? Definitely worth a comment explaining why at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the spec declared that it should be 32 bits, and without that, the Sail compiler will chuck an error, because it won't know how many bits 'm
has.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm the spec says it is reserved. I think we should maybe raise an illegal instruction exception in that case (though we still need a proper policy on how to handle reserved behaviour).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked at the spec closely enough yet, but if it is reserved it seems like it would be best to catch it at the encdec stage if possible and just not decode it as this instruction. Then it would fall through to the existing illegal instruction catch-all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that probably makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but then bits('m) would need to be bits(32) for Sail to prove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could do something like this:
let 'SEW = get_sew();
let LMUL_pow = get_lmul_pow();
let LMUL = if LMUL_pow < 0 then 0 else LMUL_pow;
let 'num_elem = get_num_elem(LMUL_pow, SEW);
if 'SEW != 32 | not(zvk_check_elements(VLEN, num_elem, LMUL, SEW)) then {
handle_illegal();
RETIRE_FAIL
} else {
let vs2_val = read_vreg(num_elem, SEW, LMUL_pow, vs2);
let vd_val = read_vreg(num_elem, SEW, LMUL_pow, vd);
let eg_len = (unsigned(vl) / 'num_elem);
...
I think that will compile. Not 100% sure though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works, thank you!
model/riscv_insts_zvkned.sail
Outdated
|
||
let eg_len = (unsigned(vl) / 'n); | ||
let eg_start = (unsigned(vstart) / 'n); | ||
let keyelem = if suffix == "vv" then 1 else 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should avoid having behaviour encoded in strings. suffix
should be an enum, not strings.
model/riscv_insts_zvkned.sail
Outdated
assert(0 <= ((i * 4) + 3) & ((i * 4) + 3) < 'n); | ||
|
||
let vd_state = get_velem(vd_val, i); | ||
let vs2_key = get_velem(vs2_val, keyelem * i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this would be something like:
let vs2_key = get_velem(vs2_val, match suffix { something_VV => i, something_VS => 0 });
(I'll leave you to come up with suitable names for whatever VV and VS mean!)
model/riscv_insts_zvkned.sail
Outdated
let vs2_key = get_velem(vs2_val, keyelem * i); | ||
let sb : bitvector(128) = aes_subbytes_fwd(vd_state); | ||
let sr : bitvector(128) = aes_shift_rows_fwd(sb); | ||
let ark : bitvector(128) = sr ^ vs2_key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bits
? Maybe before my time; is bitvector
an old version of bits
?
model/riscv_insts_zvkned.sail
Outdated
let sb : bitvector(128, dec) = aes_subbytes_fwd(vd_state); | ||
let sr : bitvector(128, dec) = aes_shift_rows_fwd(sb); | ||
let mix : bitvector(128, dec) = aes_mixcolumns_fwd(sr); | ||
let ark : bitvector(128, dec) = mix ^ vs2_key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bits(128)
. You could just delete all these, though it may be appropriate for readability.
model/riscv_insts_zvkned.sail
Outdated
assert('m == 32); | ||
|
||
let vs2_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vs2); | ||
let vd_val : vector('n, dec, bits('m)) = read_vreg(num_elem, SEW, LMUL_pow, vd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove , dec
- Sail doesn't support per-vector orders now.
You could just delete the type annotations (I would, but up to you).
model/riscv_insts_zvkned.sail
Outdated
/* VAESDM.VV */ | ||
|
||
mapping vaesdm_mnemonic : bits(7) <-> string = { | ||
0b1010001 <-> "vaesem.vv", | ||
0b1010011 <-> "vaesem.vs", | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment and mapping name states vaesdm
but the mapping itself is happening for vaesem.[vv, vs]
mnemonics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the rest of the model maps ast
to assembly; not the bits directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still need to take a look at the spec, but here are some initial comments.
function get_velem(v, i) = v[4 * i + 3] @ v[4 * i + 2] @ v[4 * i + 1] @ v[4 * i] | ||
|
||
val zvk_check_elements : (int, int, int, int) -> bool | ||
function zvk_check_elements(VLEN, num_elem, LMUL, SEW) = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With simple function declarations like this, it’s usually easier to eliminate the val line and directly integrate the types into the function line.
@@ -0,0 +1,428 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing copyright header
model/riscv_extensions.sail
Outdated
@@ -23,6 +23,7 @@ enum clause extension = Ext_C | |||
enum clause extension = Ext_B | |||
// Vector Operations | |||
enum clause extension = Ext_V | |||
enum clause extension = Ext_Zvkned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing comment with long form name of the extension. This should also be moved down to be with the rest of the Z* extensions in a new Zv* section.
model/riscv_insts_zvkned.sail
Outdated
let current_round_key = get_velem(vs2_val, i); | ||
|
||
let round_key_b = get_velem(vs2_val, i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specification states:
let CurrentRoundKey[3:0] : bits(128) = get_velem(vs2, EGW=128, i);
let RoundKeyB[3:0] : bits(32) = get_velem(vd, EGW=128, i); // Previous round key
b470e17
to
9826514
Compare
To support the implementation of Zvkned extension in SAIL, this creates the necessary infrastructure(i.e., a file to hold it, and the extension macro), preparing the tree for the Zvkned implementation. Signed-off-by: Charalampos Mitrodimas <[email protected]> Co-authored-by: KotorinMinami <[email protected]>
9826514
to
3161d3c
Compare
Implements the Zvkned (NIST Suite: Vector AES Block Cipher) extension, as of version Release 1.0.0.
The following instructions are included:
All instructions were tested with VLEN=128 and results were compared with QEMU results of each instruction.
Note
This PR was originally developed by @charmitro , and now the Vector AES Block Cipher has been released.